/**
 * TODO: mask, scroll, selectable?
 */
package com.dreamana.components
{
	import com.dreamana.ui.BaseComponent;
	import com.dreamana.ui.ISkinnable;
	import com.dreamana.ui.SkinGraphics;
	
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.text.engine.ContentElement;
	import flash.text.engine.ElementFormat;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextLine;
	
	public class TextArea extends BaseComponent implements ISkinnable
	{
		protected var _back:Shape;
		protected var _backColor:int = -1;
		protected var _backTexture:BitmapData;
		protected var _backScale9Grid:Rectangle;
		
		protected var _textBlock:TextBlock;
		protected var _textContent:ContentElement;
		protected var _lineHeight:int = 0;
		protected var _textHeight:int = 0;
		protected var _padding:Object;
		protected var _borderColor:int = -1;
		
		public function TextArea(w:int, h:int, content:ContentElement=null)
		{
			_width = w;
			_height = h;
			_padding = {top:0, right:0, bottom:0, left:0};
			_textBlock = new TextBlock();
			_textContent = content;
			
			this.init();
		}
		
		override protected function addChildren():void
		{
			_back = new Shape();
			this.addChild(_back);
		}
		
		//--- PUBLIC METHODS ---
		
		override public function draw():void
		{
			var g:Graphics = _back.graphics;
			
			g.clear();
			
			//Background
			if(_backTexture) {
				if(_backScale9Grid) SkinGraphics.fill9Grid(g, _backTexture, _width, _height, _backScale9Grid, false);
				else SkinGraphics.fillRect(g, _backTexture, _width, _height);
			}
			else if(_backColor >= 0) {
				SkinGraphics.drawBlank(g, _width, _height, _backColor);
			}
			else {
				SkinGraphics.drawWireFrame(g, _width, _height);
			}
			
			
			//Clear Text( -remain background)
			var i:int = this.numChildren;
			while(i-- > 1) this.removeChildAt(i);
			
			//Render Text
			var ox:int = _padding.left;
			var oy:int = _padding.top;
			var w:int = _width - _padding.left - _padding.right;
			var h:int = _height - _padding.top - _padding.bottom;
			
			_textBlock.content = _textContent;
			
			var line:TextLine = _textBlock.createTextLine(null, w);
			if(line != null) {
				//first line
				var py:int = oy + line.height;
				line.x = ox;
				line.y = py;
				this.addChild(line);
				
				while(true)
				{
					py = line.y + Math.max(line.height, _lineHeight);
					
					//mark textHeight
					_textHeight = py;
					
					line = _textBlock.createTextLine(line, w);
					if(line == null) break;
					line.x = ox;
					line.y = py;
					this.addChild(line);
				}
			}
			
			
			//Border
			if(_borderColor >= 0) {
				g.lineStyle(0, _borderColor);
				g.drawRect(ox, oy, w, h);
			}
		}
		
		override public function setStyle(style:String, value:Object):void
		{
			super.setStyle(style, value);
			
			switch(style) {
				case "background-color":
					_backColor = value as Number;
					invalidate();
					break;
				case "background-image":
					_backTexture = value as BitmapData;
					invalidate();
					break;
				case "background-9grid":
					_backScale9Grid = value as Rectangle;
					invalidate();
					break;
				case "line-height":
					_lineHeight = value as Number;
					invalidate();
					break;
				case "border-color":
					_borderColor = value as Number;
					invalidate();
					break;
				case "padding":
					setPadding(value as Number);
					break;
				case "padding-top":
					setPadding(value as Number, _padding.right, _padding.bottom, _padding.left);
					break;
				case "padding-right":
					setPadding(_padding.top, value as Number, _padding.bottom, _padding.left);
					break;
				case "padding-bottom":
					setPadding(_padding.top, _padding.right, value as Number, _padding.left);
					break;
				case "padding-left":
					setPadding(_padding.top, _padding.right, _padding.bottom, value as Number);
					break;
			}
		}
		
		/**
		 * padding
		 * @param args [padding | top, right, bottom, left]
		 * @return 
		 */		
		public function setPadding(...args):void
		{
			if(args.length == 1) {
				var p:int = args[0]; 
				_padding.top = p;
				_padding.right = p;
				_padding.bottom = p;
				_padding.left = p;
			}
			else if(args.length == 4) {
				_padding.top = args[0];
				_padding.right = args[1];
				_padding.bottom = args[2];
				_padding.left = args[3];
			}
			
			draw();
		}
		
		//--- EVENT HANDLERS ---
		
		
		//--- GETTER/SETTERS ---
		/*
		public function get text():String {	return _textContent.text; }
		public function set text(value:String):void {
			_textContent = new TextElement(value, new ElementFormat());
			this.draw();
		}*/
				
		public function get content():ContentElement { return _textContent; }
		public function set content(value:ContentElement):void {
			_textContent = value;
			this.draw();
		}
		
		public function get textHeight():int { return _textHeight; }
	}
}